package cn.com.yusys.yusp.admin.service;


import cn.com.yusys.yusp.admin.bean.AdminSmNoticeBean;
import cn.com.yusys.yusp.admin.domain.*;
import cn.com.yusys.yusp.admin.repository.mapper.AdminSmNoticeMapper;
import cn.com.yusys.yusp.admin.repository.mapper.AdminSmNoticeReadMapper;
import cn.com.yusys.yusp.admin.repository.mapper.AdminSmNoticeReciveMapper;
import cn.com.yusys.yusp.admin.repository.mapper.AdminSmRicheditInfoMapper;
import cn.com.yusys.yusp.admin.service.FileProviderService;
import cn.com.yusys.yusp.commons.mapper.CommonMapper;
import cn.com.yusys.yusp.commons.mapper.QueryModel;
import cn.com.yusys.yusp.commons.service.CommonService;
import cn.com.yusys.yusp.commons.util.BeanUtil;
import cn.com.yusys.yusp.commons.util.DateUtil;
import cn.com.yusys.yusp.commons.util.StringUtil;
import cn.com.yusys.yusp.file.dto.AdminFileUploadInfoDTO;
import cn.com.yusys.yusp.file.dto.AdminSmRicheditFileInfoDTO;
import cn.com.yusys.yusp.notice.dto.AdminSmNoticeDTO;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @项目名称：yusp-admin
 * @类名称：AdminSmLookupItemService
 * @类描述：数据字典内容
 * @功能描述:
 * @创建人：liaoxd@yusys.com.cn @创建时间：2017-12-13 11:18 @修改备注：
 * @修改日期 修改人员 修改原因 -------- -------- ----------------------------------------
 * @version 1.0.0
 * @Copyright (c) 2017宇信科技-版权所有
 */
@Service
public class AdminSmNoticeServiceImpl extends CommonService implements AdminSmNoticeService {

    private final static Logger logger = LoggerFactory.getLogger(AdminSmNoticeServiceImpl.class);

    @Autowired
    private AdminSmNoticeMapper mapper;

    @Autowired
    private PropProviderService propProviderService;

    @Autowired
    private AdminSmNoticeReciveMapper adminSmNoticeReciveMapper;

    @Autowired
    private AdminSmNoticeReadMapper adminSmNoticeReadMapper;

    @Autowired
    private AdminSmRicheditInfoMapper adminSmRicheditInfoMapper;

    @Autowired
    private FileProviderService fileProviderService;

    @SuppressWarnings("rawtypes")
    @Override
    protected CommonMapper getMapper() {
        return this.mapper;
    }


    /**
     * @函数名称:insertInfo
     * @函数描述:新增公告、公告内容，ID为前台传入已生成的ID
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public AdminSmNoticeBean insertInfo(Object record) {

        AdminSmNoticeBean adminSmNotice = (AdminSmNoticeBean) record;


        //String noticeId = this.getUuid();
        String noticeId = adminSmNotice.getNoticeId();

        adminSmNotice.setNoticeId(noticeId);
        adminSmNotice.setCreatorTime(DateUtil.formatDateTimeByDef());

        this.insertSelective(getMapper(), record);

        AdminSmRicheditInfo adminSmRicheditInfo = new AdminSmRicheditInfo();
        if (adminSmNotice.getContent() != null && !"".equals(adminSmNotice.getContent())) {
            adminSmRicheditInfo.setContent(this.pathReplace(adminSmNotice.getContent()));
        } else {
            adminSmRicheditInfo.setContent("");
        }

        adminSmRicheditInfo.setRelMod("NOTICE");
        adminSmRicheditInfo.setRelId(noticeId);

        this.adminSmRicheditInfoMapper.insert(adminSmRicheditInfo);


        String orgIds = adminSmNotice.getReciveOrgId();
        String roleIds = adminSmNotice.getReciveRoleId();


        //1:如果roleIds，orgIds同时为空字符串，则说明都未选，则默认为全部可查看，插入两种类型空字符串
        if ("".equals(roleIds) && "".equals(orgIds)) {
            AdminSmNoticeRecive adminSmNoticeReciverole = new AdminSmNoticeRecive();
            adminSmNoticeReciverole.setNoticeId(adminSmNotice.getNoticeId());
            adminSmNoticeReciverole.setReciveType("ROLE");
            adminSmNoticeReciverole.setReciveOgjId("NA");
            this.adminSmNoticeReciveMapper.insert(adminSmNoticeReciverole);


            AdminSmNoticeRecive adminSmNoticeReciveorg = new AdminSmNoticeRecive();
            adminSmNoticeReciveorg.setNoticeId(adminSmNotice.getNoticeId());
            adminSmNoticeReciveorg.setReciveType("ORG");
            adminSmNoticeReciveorg.setReciveOgjId("NA");
            this.adminSmNoticeReciveMapper.insert(adminSmNoticeReciveorg);
        }

        if (StringUtil.isNotBlank(roleIds)) {
            if (roleIds.contains(",")) {
                String[] roleId = roleIds.split(",");
                for (int b = 0; b < roleId.length; b++) {
                    AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                    adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                    adminSmNoticeRecive.setReciveType("ROLE");
                    adminSmNoticeRecive.setReciveOgjId(roleId[b]);
                    this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
                }

            } else {
                AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                adminSmNoticeRecive.setReciveType("ROLE");
                adminSmNoticeRecive.setReciveOgjId(roleIds);
                this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
            }
        }
        if (StringUtil.isNotEmpty(orgIds)) {
            if (orgIds.contains(",")) {
                String[] orgId = orgIds.split(",");
                for (int a = 0; a < orgId.length; a++) {

                    AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                    adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                    adminSmNoticeRecive.setReciveType("ORG");
                    adminSmNoticeRecive.setReciveOgjId(orgId[a]);
                    this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
                }

            } else {
                AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                adminSmNoticeRecive.setReciveType("ORG");
                adminSmNoticeRecive.setReciveOgjId(orgIds);
                this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
            }
        }
        return adminSmNotice;
    }

    /**
     * @函数名称:updateInfo
     * @函数描述:修改公告、公告内容并返回ID
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int updateInfo(Object record) {


        AdminSmNoticeBean adminSmNotice = (AdminSmNoticeBean) record;

        AdminSmRicheditInfo adminSmRicheditInfo = new AdminSmRicheditInfo();
        adminSmRicheditInfo.setContent(adminSmNotice.getContent());
        adminSmRicheditInfo.setRelMod("NOTICE");
        adminSmRicheditInfo.setRelId(adminSmNotice.getNoticeId());
        adminSmRicheditInfo.setRicheditId(adminSmNotice.getRicheditId());

        this.adminSmRicheditInfoMapper.updateByPrimaryKeySelective(adminSmRicheditInfo);


        String orgIds = adminSmNotice.getReciveOrgId();
        String roleIds = adminSmNotice.getReciveRoleId();


        //1:如果roleIds，orgIds同时为空字符串，则说明都未选，则默认为全部可查看，插入两种类型空字符串
        if ("".equals(roleIds) && "".equals(orgIds)) {
            AdminSmNoticeRecive adminSmNoticeReciverole = new AdminSmNoticeRecive();
            adminSmNoticeReciverole.setNoticeId(adminSmNotice.getNoticeId());
            adminSmNoticeReciverole.setReciveType("ROLE");
            //先删除再新增 ，无法做修改逻辑
            this.adminSmNoticeReciveMapper.delete(adminSmNoticeReciverole);
            adminSmNoticeReciverole.setReciveOgjId("NA");
            this.adminSmNoticeReciveMapper.insert(adminSmNoticeReciverole);


            AdminSmNoticeRecive adminSmNoticeReciveorg = new AdminSmNoticeRecive();
            adminSmNoticeReciveorg.setNoticeId(adminSmNotice.getNoticeId());
            adminSmNoticeReciveorg.setReciveType("ORG");
            //先删除再新增 ，无法做修改逻辑
            this.adminSmNoticeReciveMapper.delete(adminSmNoticeReciveorg);
            adminSmNoticeReciveorg.setReciveOgjId("NA");
            this.adminSmNoticeReciveMapper.insert(adminSmNoticeReciveorg);
        }
        //2:如果roleIds不为空字符串，则说明选择了角色，则默认为只有选择的角色可见，只插入角色字符串
        if (!"".equals(roleIds) || !"".equals(orgIds)) {
            AdminSmNoticeRecive adminSmNoticeRecivedel = new AdminSmNoticeRecive();
            adminSmNoticeRecivedel.setNoticeId(adminSmNotice.getNoticeId());
            //先删除再新增 ，无法做修改逻辑
            this.adminSmNoticeReciveMapper.delete(adminSmNoticeRecivedel);
            if (!"".equals(roleIds)) {
                if (roleIds.contains(",")) {
                    String[] roleId = roleIds.split(",");
                    for (int b = 0; b < roleId.length; b++) {
                        AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                        adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                        adminSmNoticeRecive.setReciveType("ROLE");
                        adminSmNoticeRecive.setReciveOgjId(roleId[b]);
                        this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
                    }

                } else {
                    AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                    adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                    adminSmNoticeRecive.setReciveType("ROLE");
                    adminSmNoticeRecive.setReciveOgjId(roleIds);
                    this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
                }
            }
            if (!"".equals(orgIds)) {
                if (orgIds.contains(",")) {
                    String[] orgId = orgIds.split(",");
                    for (int a = 0; a < orgId.length; a++) {
                        AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                        adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                        adminSmNoticeRecive.setReciveType("ORG");
                        adminSmNoticeRecive.setReciveOgjId(orgId[a]);
                        this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
                    }

                } else {
                    AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
                    adminSmNoticeRecive.setNoticeId(adminSmNotice.getNoticeId());
                    adminSmNoticeRecive.setReciveType("ORG");
                    adminSmNoticeRecive.setReciveOgjId(orgIds);
                    this.adminSmNoticeReciveMapper.insert(adminSmNoticeRecive);
                }
            }
        }
        return this.updateSelective(getMapper(), record);
    }


    /**
     * @函数名称:pubNotice
     * @函数描述:发布通知
     * @参数与返回说明:
     * @算法描述:
     */
    public int pubNotice(List<AdminSmNotice> list) {
        int size = 0;
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                AdminSmNotice adminSmNotice = (AdminSmNotice) list.get(i);

                //查询是否有阅读记录，如果未阅读则不允许发布
//                AdminSmNoticeRead read = new AdminSmNoticeRead();
//                read.setNoticeId(adminSmNotice.getNoticeId());
//                List<AdminSmNoticeRead> readList = this.adminSmNoticeReadMapper.select(read);
//                if (readList == null || readList.size() == 0) {
//                    //size = -1;
//                    return -1;
//                }

                adminSmNotice.setPubTime(DateUtil.formatDateTimeByDef());
                mapper.pubNoticeList(adminSmNotice);
//                this.updateSelective(getMapper(), adminSmNotice);
            }
            size = list.size();
        }
        return size;
    }


    /**
     * @函数名称:readNotice
     * @函数描述:阅读记录
     * @参数与返回说明:
     * @算法描述:
     */
    public int readNotice(List<AdminSmNoticeBean> list) {
        int size = 0;
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                AdminSmNoticeBean adminSmNotice = (AdminSmNoticeBean) list.get(i);
                AdminSmNoticeRead adminSmNoticeRead = new AdminSmNoticeRead();

                adminSmNoticeRead.setNoticeId(adminSmNotice.getNoticeId());
                adminSmNoticeRead.setReadTime(DateUtil.formatDateTimeByDef());
                adminSmNoticeRead.setUserId(adminSmNotice.getReadUserId());
                this.adminSmNoticeReadMapper.insert(adminSmNoticeRead);
            }
            size = list.size();
        }

        return size;
    }


    /**
     * @函数名称:selectByModel
     * @函数描述:支持页面模糊查询
     * @参数与返回说明:
     * @算法描述:
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public <T> List<T> selectByModel(QueryModel model) {
        if (model.getCondition().containsKey("noticeTitle")) {
            model.getCondition().put("noticeTitle", "%" + model.getCondition().get("noticeTitle") + "%");
        }
        if (model.getCondition().containsKey("roles")) {
            List list = (List) model.getCondition().get("roles");
            if (list != null && list.size() > 0) {
                model.getCondition().put("roles", list);
            }
        }

        // 设置分页查询参数(设置到线程变量中了)
        PageHelper.startPage(model.getPage(), model.getSize());
        List<Map<String, String>> list = this.mapper.getNoticeListByparams(model);
        // 清除线程绑定的分页参数，防止影响同线程的其他查询

        PageHelper.clearPage();

        return (List<T>) list;
    }


    /**
     * @函数名称:getNoticeByNoticeId
     * @函数描述:查询公告详情，包含富文本内容、接收对象
     * @参数与返回说明:
     * @算法描述:
     */
    public List<Map<String,String>> getNoticeByNoticeId(String id) {
        Map<String,String> map = new HashMap<String, String>();
        map.put("noticeId", id);
        List<Map<String,String>> list=this.mapper.getNoticeByNoticId(map);
        //富文本内容替换缺省值 $HOST为系统参数配置
        if(list!=null && list.size()>0) {
            try {
                if(list.get(0).get("detailcontent")!= null && list.get(0).get("detailcontent").contains("pathtrs")) {
                    list.get(0).put("detailcontent", this.pathRestore(list.get(0).get("detailcontent")));
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }

        return list;
    }

    /**
     * @函数名称:delete
     * @函数描述:重写删除方法，需要删除本身以及附件
     * @参数与返回说明:
     * @算法描述:
     */
    @Override
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int deleteByPrimaryKey(Object record) {

        int count = this.deleteByPrimaryKey(getMapper(), record);

        //删除接收对象信息
        AdminSmNoticeRecive adminSmNoticeRecive = new AdminSmNoticeRecive();
        adminSmNoticeRecive.setNoticeId(String.valueOf(record));
        int reciveResult = this.adminSmNoticeReciveMapper.delete(adminSmNoticeRecive);

        //删除阅读信息
        AdminSmNoticeRead  adminSmNoticeRead = new AdminSmNoticeRead();
        adminSmNoticeRead.setNoticeId(String.valueOf(record));
        int readResult = this.adminSmNoticeReadMapper.delete(adminSmNoticeRead);

        //删除富文本信息
        AdminSmRicheditInfo adminSmRicheditInfo = new AdminSmRicheditInfo();
        adminSmRicheditInfo.setRelId(String.valueOf(record));
        int richeditResult = this.adminSmRicheditInfoMapper.delete(adminSmRicheditInfo);

        logger.info("Delete notice information,noticeId:{},result:{}", String.valueOf(record), count);
        logger.info("Delete receiving object information,noticeId:{},result:{}", String.valueOf(record), reciveResult);
        logger.info("Delete reading information,noticeId:{},result:{}", String.valueOf(record), readResult);
        logger.info("Delete rich text information,noticeId:{},result:{}", String.valueOf(record), richeditResult);


        QueryModel model = new QueryModel();
        Map<String,String> map = new HashMap<String,String>();
        map.put("busNo", record.toString());
        ObjectMapper jsonObj = new ObjectMapper();

        try {
            model.setCondition(jsonObj.writeValueAsString(map));
            //删除附件
            String paths = this.getFilePaths(model);
            fileProviderService.deleteFileRecods(paths);
            //删除富文本附件
            String richeditFilePaths = this.getRicheditFilePaths(model);
            fileProviderService.deleteRicheidtFileRecods(richeditFilePaths);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }


        return count;
    }


    /**
     * @函数名称:pathReplay
     * @函数描述:替换path为缺省模式，便于配置化
     * @参数与返回说明:
     * @算法描述:
     */
    private String pathReplace(String filePath) {
        if (filePath.contains("pathtrs")) {
            // 1:摘取协议
            String telMode = "((http|ftp|https))";
            Pattern telp = Pattern.compile(telMode);
            Matcher telm = telp.matcher(filePath);
            while (telm.find()) {
                String tel = telm.group();
                System.out.println("Mapping to protocol:" + tel);

                filePath = filePath.replace(tel, "-AGRE-");

                System.out.println("src:" + tel);
                System.out.println(filePath);

            }
            // 2:摘取HOST
            String hostMode = "(//[a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})|(//[0-9]{1,3}(\\.[0-9]{1,3}){3})";
            Pattern hostp = Pattern.compile(hostMode);
            Matcher hostm = hostp.matcher(filePath);
            while (hostm.find()) {
                String host = hostm.group();

                filePath = filePath.replace(host, "-HOST-");

            }
            // 3:摘取端口
            String portMode = "(:\\d+)";

            Pattern portp = Pattern.compile(portMode);
            Matcher portm = portp.matcher(filePath);
            while (portm.find()) {
                String port = portm.group();

                filePath = filePath.replace(port, "-PORT-");
            }
        }
        return filePath;
    }

    /**
     * @throws JsonProcessingException
     * @函数名称:pathReplay
     * @函数描述:替换path的缺省值，还原path
     * @参数与返回说明:
     * @算法描述:
     */
    private String pathRestore(String path) throws Exception {
        return propProviderService.pathRestore(path);
    }
    /**
     * @函数名称:getFilePaths
     * @函数描述:获取附件pathS
     * @参数与返回说明:
     * @算法描述:
     */
    public String getFilePaths(QueryModel model) {
        List<AdminFileUploadInfoDTO> list = this.fileProviderService.selectFileUploadByModel(model.getCondition());
        String fileIds = "";
        if(list !=null && list.size() >0 ) {
            for(int i=0;i<list.size();i++) {
                if( i==0) {
                    fileIds = list.get(i).getFilePath();
                }else {
                    fileIds = fileIds +","+ list.get(i).getFilePath();
                }
            }
        }

        return fileIds;
    }

    /**
     * @函数名称:getFileIds
     * @函数描述:获取附件IDS
     * @参数与返回说明:
     * @算法描述:
     */
    public String getFileIds(QueryModel model) {
        List<AdminFileUploadInfoDTO> list = this.fileProviderService.selectFileUploadByModel(model.getCondition());
        String fileIds = "";
        if(list !=null && list.size() >0 ) {
            for(int i=0;i<list.size();i++) {
                if( i==0) {
                    fileIds = list.get(i).getFileId();
                }else {
                    fileIds = fileIds +","+ list.get(i).getFileId();
                }
            }
        }

        return fileIds;
    }


    /**
     * @函数名称:getRicheditFilePaths
     * @函数描述:获取富文本附件pathS
     * @参数与返回说明:
     * @算法描述:
     */
    public String getRicheditFilePaths(QueryModel model) {
        List<AdminSmRicheditFileInfoDTO> list = this.fileProviderService.selectRicheditFileByModel(model.getCondition());
        String fileIds = "";
        if(list !=null && list.size() >0 ) {
            for(int i=0;i<list.size();i++) {
                if( i==0) {
                    fileIds = list.get(i).getFilePath();
                }else {
                    fileIds = fileIds +","+ list.get(i).getFilePath();
                }
            }
        }

        return fileIds;
    }
    
    /**
     * 单体化微服务改造
     * @param adminSmNoticeDto
     * @return
     */
    public int noticeInsert(AdminSmNoticeDTO adminSmNoticeDto) {
    	AdminSmNoticeBean notice = BeanUtil.beanCopy(adminSmNoticeDto, AdminSmNoticeBean.class);
    	notice.setContent(adminSmNoticeDto.getNoticeContent());
	    this.insertInfo(notice);
        return 1;
    }

}
